package com.diaohw.module.auth.service.impl;

import com.diaohw.module.auth.service.LoginService;
import com.diaohw.platform.common.exception.GlobalException;
import com.diaohw.platform.common.obj.login.LoginUser;
import com.diaohw.platform.common.obj.login.LoginVo;
import com.diaohw.platform.common.util.CryptoUtil;
import com.diaohw.platform.framework.authorization.AuthorizationInterface;
import com.diaohw.platform.framework.authorization.AuthorizationUtil;
import com.diaohw.platform.framework.redis.util.RedisStringUtil;
import com.diaohw.platform.framework.web.util.IpUtil;
import com.diaohw.platform.framework.web.util.UserAgentUtil;
import com.diaohw.platform.remote.auth.AuthRemoteService;
import com.diaohw.platform.remote.auth.enums.AccountStateEnum;
import com.diaohw.platform.remote.auth.obj.bo.*;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import static com.diaohw.platform.framework.authorization.OnlineManager.LOGIN_ACCOUNT_INFO;


@Service
public class LoginImpl implements LoginService {

    @Resource
    private AuthRemoteService authRemoteService;
    @Resource
    private AuthorizationInterface authorizationInterface;

    @Override
    public LoginVo login(LoginBO login) {

        List<AccountSaltBO> list = authRemoteService.username(login.getUsername());
        if (list == null || list.size() != 1) {
            throw new GlobalException("账号或者密码输入错误");
        }
        AccountSaltBO salt = list.get(0);
        String md5 = CryptoUtil.md5(salt.getSalt(), login.getPassword());

        if (!md5.equals(salt.getPassword())) {
            throw new GlobalException("账号或者密码输入错误");
        }

        if (salt.stateEnum() != AccountStateEnum.NORMAL) {
            throw new GlobalException("您的账号已 【" + salt.stateEnum().name + "】");
        }

        AccountInfoBO info = authRemoteService.accountInfo(salt.getId());
        info.getAccount().setRoleCode(info.getRoles().stream().map(RoleBO::getRoleCode).collect(Collectors.joining(",")));
        LoginUser build = LoginUser.builder()
                .loginId(info.getAccount().getId())
                .username(login.getUsername())
                .nickname(info.getAccount().getNickname())
                .departmentId(info.getAccount().getDepartmentId())
                .build();

        info.setLoginTime(LocalDateTime.now());
        RedisStringUtil.setValue(LOGIN_ACCOUNT_INFO.apply(salt.getId()), info);
        sendLoginLog(info.getAccount());

        if (info.getPermissions() != null) {
            authorizationInterface.setPermissionList(build.getLoginId(), null, info.getPermissions().stream().map(PermissionBO::getPermissionCode).toList());
        }
        if (info.getRoles() != null) {
            authorizationInterface.setRoleList(build.getLoginId(), null, info.getRoles().stream().map(RoleBO::getRoleCode).toList());
        }

        return AuthorizationUtil.login(build);
    }

    @Override
    public boolean reset(PasswordBO password) {
        String longId = AuthorizationUtil.getLoginId();
        password.setAccountId(longId);
        return authRemoteService.reset(password);
    }

    @Override
    public AccountInfoBO me() {
        return RedisStringUtil.getValue(LOGIN_ACCOUNT_INFO.apply(AuthorizationUtil.getLoginId()));
    }


    private void sendLoginLog(AccountBO account) {
        String ip = IpUtil.addr();
        String browser = UserAgentUtil.browser();
        LoginLogBO log = LoginLogBO.create(account.getId(), account.getUsername(), account.getNickname(), ip, browser);
        authRemoteService.loginLog(log);
    }


}
